<!--轮播使用方式
<my-carousel :imgList="listData"></my-carousel>
-->

<template>
	<view class="my-carousel-box" :style="{ height: imgHeight + 'rpx' }" v-if="listData.length > 0">
		<view
			class="carousel-item"
			:animation="item.aData ? item.aData[0] : {}"
			v-for="(item, index) in listData"
			:key="index"
			:style="{
				zIndex: index === currentIndex ? 4 : item.isSecond ? 3 : item.isHide ? 1 : 2,
			}"
			@tap.stop="toPage(item)"
		>
			<view
				class="carousel-img"
				:style="{
					background: `url(${item[imgKey]}) center center no-repeat`,
					backgroundSize: `cover`,
					borderRadius: imgRadius + 'rpx',
					width: imgWidth + 'rpx',
				}"
			></view>
		</view>
	</view>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from "vue"
import { onHide, onShow } from "@dcloudio/uni-app"
import { navigateTo } from "@/utils/page-redirect"

const props = defineProps({
	imgList: {
		type: Array,
		default: () => [],
	},
	imgKey: { type: String, default: "cover_url" }, // 图片的key
	currentIndexParameter: { type: Number, default: 0 }, // 当前显示的图片索引
	imgWidth: { type: String, default: "220" }, //	图片宽度，单位rpx
	imgHeight: { type: String, default: "296" }, //	图片高度，单位rpx
	imgRadius: { type: String, default: "16" }, // 图片圆角，单位rpx
	moveWidthParam: { type: Number, default: 0.21 }, // 移动距离占图片宽度的比例
})
const emit = defineEmits(["currentRegion"])

const listData = ref<any>([])
const startData = ref<any>({ clientX: 0 })
const moveWidth = ref(0)
const currentIndex = ref(props.currentIndexParameter)
let intervalId: any = null

const toPage = (item: any) => {
	navigateTo(`/pages/hy/district/detail?id=${item.id}`)
}

const start = (e: TouchEvent) => {
	startData.value.clientX = e.changedTouches[0].clientX
}

const end = (e: TouchEvent) => {
	let thisIndex = currentIndex.value
	const subX = e.changedTouches[0].clientX - startData.value.clientX
	let leftIndex = thisIndex === 0 ? listData.value.length - 1 : thisIndex - 1
	let rightIndex = thisIndex === listData.value.length - 1 ? 0 : thisIndex + 1
	if (subX > 20) {
		let showIndex = leftIndex === 0 ? listData.value.length - 1 : leftIndex - 1
		currentIndex.value = leftIndex
		listData.value[rightIndex].isSecond = false
		listData.value[rightIndex].isHide = true
		listData.value[thisIndex].isSecond = true
		listData.value[showIndex].isHide = false
		toHide(rightIndex, listData.value[leftIndex].aData![1])
		toRight(thisIndex, listData.value[thisIndex].aData![1])
		toMid(leftIndex, listData.value[leftIndex].aData![1])
		toLeft(showIndex, listData.value[showIndex].aData![1])
	} else if (subX < -20) {
		let showIndex = rightIndex === listData.value.length - 1 ? 0 : rightIndex + 1
		currentIndex.value = rightIndex
		if (listData.value[thisIndex]) {
			listData.value[thisIndex].isSecond = true
			listData.value[showIndex].isHide = false
			listData.value[leftIndex].isSecond = false
			listData.value[leftIndex].isHide = true
		}
		toHide(leftIndex, listData.value[leftIndex]?.aData![1])
		toLeft(thisIndex, listData.value[thisIndex]?.aData![1])
		toMid(rightIndex, listData.value[rightIndex]?.aData![1])
		toRight(showIndex, listData.value[leftIndex]?.aData![1])
	}
}

const toMid = (index: number, animation: any) => {
	animation.rotate(0).scale(1).translateX(0).translateY(0).opacity(1).step()
	listData.value[index].aData![0] = animation.export()
}

const toLeft = (index: number, animation: any) => {
	animation.rotate(-11).scale(0.83).translateX(-moveWidth.value).translateY(8).opacity(0).step()
	listData.value[index].aData![0] = animation.export()
}

const toRight = (index: number, animation: any) => {
	animation.rotate(11).scale(0.83).translateX(moveWidth.value).translateY(-8).opacity(1).step()
	listData.value[index].aData![0] = animation.export()
}

const toHide = (index: number, animation: any) => {
	animation.rotate(0).scale(1).opacity(0).translateX(0).translateY(0).step()
	listData.value[index].aData![0] = animation.export()
}

const startAutoplay = () => {
	if (listData.value.length === 0) return

	intervalId = setInterval(() => {
		// 模拟手动滑动
		end({ changedTouches: [{ clientX: startData.value.clientX - 30 }] })
	}, 3000)
}
const stopAutoplay = () => {
	clearInterval(intervalId)
}

watch(
	() => props.imgList,
	(newVal) => {
		if (newVal) {
			listData.value = newVal
			moveWidth.value = parseInt(props.imgWidth) * props.moveWidthParam
			currentIndex.value = props.currentIndexParameter

			if (listData.value.length <= 1) return

			listData.value.forEach((item: any) => {
				let animation = uni.createAnimation({
					duration: 1000,
					timingFunction: "ease",
				})
				item.aData = [{}, animation]
				item.isHide = true
				item.isSecond = false
			})

			if (listData.value[0]) {
				listData.value[0].isHide = false
				toMid(0, listData.value[0]?.aData![1])
			}
			if (listData.value[1]) {
				toRight(1, listData.value[1]?.aData![1])
				listData.value[1].isSecond = true
			}
			if (listData.value.length > 2) {
				listData.value.slice(2).forEach((_: any, i: number) => {
					toHide(i + 2, listData.value[i + 2].aData![1])
				})
			}
			startAutoplay()
		}
	}
)
onMounted(() => {})

onShow(() => {
	startAutoplay()
})
onHide(() => {
	stopAutoplay()
})

onBeforeUnmount(() => {
	stopAutoplay()
})
</script>

<style lang="scss" scoped>
.my-carousel-box {
	position: relative;
	width: 100%;

	.carousel-item {
		position: absolute;
		top: 0;
		left: 0;
		height: 100%;
		z-index: 3;
		will-change: transform;

		.carousel-img {
			will-change: transform;
			border: 4rpx solid #fff;
			width: 100%;
			height: 100%;
		}
	}
}
</style>
